{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/pinecone-io/examples/blob/master/learn/recommendation/product-recommender/product_recommender.ipynb) [![Open nbviewer](https://raw.githubusercontent.com/pinecone-io/examples/master/assets/nbviewer-shield.svg)](https://nbviewer.org/github/pinecone-io/examples/blob/master/learn/recommendation/product-recommender/product_recommender.ipynb)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "YmdWGrw4t5G2"
   },
   "source": [
    "# Product Recommendation Engine"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "lXd46ecEt5G7"
   },
   "source": [
    "Learn how to build a product recommendation engine using collaborative filtering and Pinecone.\n",
    "\n",
    "In this example, we will generate product recommendations for ecommerce customers based on previous orders and trending items. This example covers preparing the vector embeddings, creating and deploying the Pinecone service, writing data to Pinecone, and finally querying Pinecone to receive a ranked list of recommended products."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "🚨 _Note that running this on CPU is slow! If running on Google Colab you go to **Runtime > Change runtime type > Hardware accelerator > GPU** to switch to GPU._\n",
    "\n",
    "---"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "XvrvUTLvt5G7"
   },
   "source": [
    "## Data Preparation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mWARNING: You are using pip version 22.0.4; however, version 23.1.2 is available.\n",
      "You should consider upgrading via the '/home/jelena/.pyenv/versions/3.8.16/envs/pinecone-product-recommender/bin/python3.8 -m pip install --upgrade pip' command.\u001b[0m\u001b[33m\n",
      "\u001b[0m"
     ]
    }
   ],
   "source": [
    "!pip install -qU numpy pandas scipy"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "dG4733cIt5G8"
   },
   "source": [
    "**Import Python Libraries**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "id": "emp_MSXZt5G8"
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import time\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import scipy.sparse as sparse\n",
    "import itertools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mWARNING: You are using pip version 22.0.4; however, version 23.1.2 is available.\n",
      "You should consider upgrading via the '/home/jelena/.pyenv/versions/3.8.16/envs/pinecone-product-recommender/bin/python3.8 -m pip install --upgrade pip' command.\u001b[0m\u001b[33m\n",
      "\u001b[0m"
     ]
    }
   ],
   "source": [
    "!pip install -qU kaggle"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "try:\n",
    "    import kaggle\n",
    "except OSError as e:\n",
    "    print(e)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The first time you `import kaggle` you will see an `OSError`, that is because we need to add our Kaggle credentials to the `/root/.kaggle/kaggle.json` file. You can find these credentials on [Kaggle](https://kaggle.com) by accessing your profile in the top-right corner of the page. This will download a `kaggle.json` file which contains your username and secret key. You can enter them below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "\n",
    "with open('/root/.kaggle/kaggle.json', 'w') as fp:\n",
    "    fp.write(json.dumps({\"username\":\"YOUR_USERNAME\",\"key\":\"YOUR_SECRET_KEY\"}))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can download the dataset:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Downloading instacart-market-basket-analysis.zip to /home/jelena/Projects/Pinecone/examples/recommendation/product-recommender\n",
      "100%|███████████████████████████████████████▉| 196M/196M [00:27<00:00, 9.01MB/s]\n",
      "100%|████████████████████████████████████████| 196M/196M [00:27<00:00, 7.36MB/s]\n"
     ]
    }
   ],
   "source": [
    "!kaggle competitions download -c instacart-market-basket-analysis"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This downloads a set of zip files, we extract them like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import zipfile\n",
    "\n",
    "files = [\n",
    "    'instacart-market-basket-analysis.zip',\n",
    "    'order_products__train.csv.zip',\n",
    "    'order_products__prior.csv.zip',\n",
    "    'products.csv.zip',\n",
    "    'orders.csv.zip'\n",
    "]\n",
    "\n",
    "for filename in files:\n",
    "    with zipfile.ZipFile(filename, 'r') as zip_ref:\n",
    "        zip_ref.extractall('./')"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can move on to loading the dataset."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "xYHyJO15t5G-"
   },
   "source": [
    "**Load the (Example) Instacart Data**"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "Oxgd8tjXt5G-"
   },
   "source": [
    "We are going to use the [Instacart Market Basket Analysis](https://www.kaggle.com/c/instacart-market-basket-analysis/data) dataset for this task.\n",
    "\n",
    "The data used throughout this example is a set of files describing customers' orders over time. The main focus is on the *orders.csv* file, where each line represents a relation between a user and the order. In other words, each line has information on *userid* (user who made the order) and *orderid*. Note there is no information about products in this table. Product information related to specific orders is stored in the *order_product__*.csv* dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "id": "cBbbR7Rut5G_"
   },
   "outputs": [],
   "source": [
    "order_products_train = pd.read_csv('order_products__train.csv')\n",
    "order_products_prior = pd.read_csv('order_products__prior.csv')\n",
    "products = pd.read_csv('products.csv')\n",
    "orders = pd.read_csv('orders.csv')\n",
    "\n",
    "order_products = pd.concat([order_products_train, order_products_prior])"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "XecuCyNlt5HA"
   },
   "source": [
    "**Preparing data for the model**\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "5FV_GGjst5HA"
   },
   "source": [
    "The Collaborative Filtering model used in this example requires only users’ historical preferences on a set of items. As there is no explicit rating in the data we are using, the purchase quantity can represent a “confidence” in terms of how strong the interaction was between the user and the products.\n",
    "\n",
    "The dataframe data will store this data and will be the base for the model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "id": "ZjRh7RYpt5HB"
   },
   "outputs": [],
   "source": [
    "customer_order_products = pd.merge(orders, order_products, how='inner',on='order_id')\n",
    "\n",
    "# creating a table with \"confidences\"\n",
    "data = customer_order_products.groupby(['user_id', 'product_id'])[['order_id']].count().reset_index()\n",
    "data.columns=[\"user_id\", \"product_id\", \"total_orders\"]\n",
    "data.product_id = data.product_id.astype('int64')\n",
    "\n",
    "# Create a lookup frame so we can get the product names back in readable form later.\n",
    "products_lookup = products[['product_id', 'product_name']].drop_duplicates()\n",
    "products_lookup['product_id'] = products_lookup.product_id.astype('int64')"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "77lvwm0St5HC"
   },
   "source": [
    "We will create two prototype users here and add them to our data dataframe. Each user will be buying only a specific product:\n",
    "- The first user will be buying only **Mineral Water**\n",
    "- The second user will be buying baby products: **No More Tears Baby Shampoo** and **Baby Wash & Shampoo**\n",
    "\n",
    "These users will be later used for querying and examination of the model results."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "id": "A06EfAf-t5HC",
    "outputId": "d040560e-4401-47d4-8749-fb1bb9397a29"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>product_id</th>\n",
       "      <th>total_orders</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>206210</td>\n",
       "      <td>22802</td>\n",
       "      <td>97</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>206211</td>\n",
       "      <td>26834</td>\n",
       "      <td>89</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>206211</td>\n",
       "      <td>12590</td>\n",
       "      <td>77</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   user_id  product_id  total_orders\n",
       "0   206210       22802            97\n",
       "1   206211       26834            89\n",
       "2   206211       12590            77"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data_new = pd.DataFrame([[data.user_id.max() + 1, 22802, 97],\n",
    "                         [data.user_id.max() + 2, 26834, 89],\n",
    "                         [data.user_id.max() + 2, 12590, 77]\n",
    "                        ], columns=['user_id', 'product_id', 'total_orders'])\n",
    "data_new"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "id": "mNIJ2hq6t5HD",
    "outputId": "cf155dc8-82ba-4f29-9cba-49d8a5052db9"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>product_id</th>\n",
       "      <th>total_orders</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>13863744</th>\n",
       "      <td>206209</td>\n",
       "      <td>48697</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13863745</th>\n",
       "      <td>206209</td>\n",
       "      <td>48742</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13863746</th>\n",
       "      <td>206210</td>\n",
       "      <td>22802</td>\n",
       "      <td>97</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13863747</th>\n",
       "      <td>206211</td>\n",
       "      <td>26834</td>\n",
       "      <td>89</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13863748</th>\n",
       "      <td>206211</td>\n",
       "      <td>12590</td>\n",
       "      <td>77</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          user_id  product_id  total_orders\n",
       "13863744   206209       48697             1\n",
       "13863745   206209       48742             2\n",
       "13863746   206210       22802            97\n",
       "13863747   206211       26834            89\n",
       "13863748   206211       12590            77"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = pd.concat([data, data_new]).reset_index(drop = True)\n",
    "data.tail()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "xBC-8PFTt5HD"
   },
   "source": [
    "In the next step, we will first extract user and item unique ids, in order to create a CSR (Compressed Sparse Row) matrix. \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "id": "v2_2R7zmt5HE"
   },
   "outputs": [],
   "source": [
    "users = list(np.sort(data.user_id.unique()))\n",
    "items = list(np.sort(products.product_id.unique()))\n",
    "purchases = list(data.total_orders)\n",
    "\n",
    "# create zero-based index position <-> user/item ID mappings\n",
    "index_to_user = pd.Series(users)\n",
    "\n",
    "# create reverse mappings from user/item ID to index positions\n",
    "user_to_index = pd.Series(data=index_to_user.index + 1, index=index_to_user.values)\n",
    "\n",
    "# create zero-based index position <-> item/user ID mappings\n",
    "index_to_item = pd.Series(items)\n",
    "\n",
    "# create reverse mapping from item/user ID to index positions\n",
    "item_to_index = pd.Series(data=index_to_item.index, index=index_to_item.values)\n",
    "\n",
    "# Get the rows and columns for our new matrix\n",
    "products_rows = data.product_id.astype(int)\n",
    "users_cols = data.user_id.astype(int)\n",
    "\n",
    "# Create a sparse matrix for our users and products containing number of purchases\n",
    "sparse_product_user = sparse.csr_matrix((purchases, (products_rows, users_cols)), shape=(len(items) + 1, len(users) + 1))\n",
    "sparse_product_user.data = np.nan_to_num(sparse_product_user.data, copy=False)\n",
    "\n",
    "sparse_user_product = sparse.csr_matrix((purchases, (users_cols, products_rows)), shape=(len(users) + 1, len(items) + 1))\n",
    "sparse_user_product.data = np.nan_to_num(sparse_user_product.data, copy=False)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "VrHSgtvht5HE"
   },
   "source": [
    "## Implicit Model"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "II6wOH96t5HF"
   },
   "source": [
    "In this section we will demonstrate creation and training of a recommender model using the **implicit** library. The recommendation model is based off the algorithms described in the paper [Collaborative Filtering for Implicit Feedback Datasets](https://www.researchgate.net/publication/220765111_Collaborative_Filtering_for_Implicit_Feedback_Datasets) with performance optimizations described in [Applications of the Conjugate Gradient Method for Implicit Feedback Collaborative Filtering](https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.379.6473&rep=rep1&type=pdf).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "id": "OFHfWKD9t5HF"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mWARNING: You are using pip version 22.0.4; however, version 23.1.2 is available.\n",
      "You should consider upgrading via the '/home/jelena/.pyenv/versions/3.8.16/envs/pinecone-product-recommender/bin/python3.8 -m pip install --upgrade pip' command.\u001b[0m\u001b[33m\n",
      "\u001b[0m"
     ]
    }
   ],
   "source": [
    "!pip install -qU implicit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "colab": {
     "referenced_widgets": [
      "f9f40f34ce41471e9385b2745c39df66"
     ]
    },
    "id": "k0GW99kxt5HF",
    "outputId": "6dccdd29-eea1-421e-d2b3-cd87c588c606"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/jelena/.pyenv/versions/3.8.16/envs/pinecone-product-recommender/lib/python3.8/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n",
      "100%|██████████| 50/50 [12:30<00:00, 15.02s/it]\n"
     ]
    }
   ],
   "source": [
    "import implicit\n",
    "from implicit import evaluation\n",
    "\n",
    "#split data into train and test sets\n",
    "train_set, test_set = evaluation.train_test_split(sparse_user_product, train_percentage=0.9)\n",
    "\n",
    "# initialize a model\n",
    "model = implicit.als.AlternatingLeastSquares(factors=100,\n",
    "                                             regularization=0.05,\n",
    "                                             iterations=50,\n",
    "                                             num_threads=1)\n",
    "\n",
    "alpha_val = 15\n",
    "train_set = (train_set * alpha_val).astype('double')\n",
    "\n",
    "# train the model on a sparse matrix of item/user/confidence weights\n",
    "model.fit(train_set, show_progress = True)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "yN80hSojt5HF"
   },
   "source": [
    "We will evaluate the model using the inbuilt library function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "colab": {
     "referenced_widgets": [
      "9611edb2a0584f3e88f2c8f0aac1c86d"
     ]
    },
    "id": "BbD8of_nt5HG",
    "outputId": "7fdb7da2-a4b2-47ba-d93e-2463c9a40004"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 193027/193027 [01:22<00:00, 2331.67it/s]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'precision': 0.2749977629022807,\n",
       " 'map': 0.04447513449736459,\n",
       " 'ndcg': 0.1442493819257263,\n",
       " 'auc': 0.6550438975250414}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_set = (test_set * alpha_val).astype('double')\n",
    "evaluation.ranking_metrics_at_k(model, train_set, test_set, K=100,\n",
    "                         show_progress=True, num_threads=1)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "LNmva3Dlt5HG"
   },
   "source": [
    "This is what item and user factors look like. These vectors will be stored in our vector index later and used for recommendation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "id": "JUtCROQKt5HG",
    "outputId": "af356153-eed8-4457-fe64-94c1607f1abc"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 7.62302289e-03, -1.87499879e-03, -2.67132535e-04,\n",
       "        -1.98393618e-03,  1.25893755e-02,  2.26164684e-02,\n",
       "        -2.98452517e-03,  1.48304272e-03,  4.13032155e-03,\n",
       "         1.40623152e-02,  7.02867238e-03,  1.75751895e-02,\n",
       "        -8.48765578e-03,  7.23443553e-03,  1.19221059e-03,\n",
       "         2.13307124e-02,  1.94959883e-02,  5.55894384e-03,\n",
       "         5.24600095e-04,  4.55727894e-03,  8.32605269e-03,\n",
       "         2.58112140e-03, -4.82219504e-04, -1.20439762e-02,\n",
       "         2.47381651e-03,  1.28009180e-02,  2.08530622e-03,\n",
       "        -3.33145494e-03,  1.92555189e-02,  4.34594555e-03,\n",
       "        -6.63968595e-03,  5.56971226e-03,  6.72743656e-03,\n",
       "         2.78714020e-03, -2.83625396e-03, -6.03283104e-03,\n",
       "         8.45496822e-03,  1.18931178e-02,  2.10034065e-02,\n",
       "        -1.68929249e-02,  1.79267656e-02, -9.86911077e-03,\n",
       "         1.26773408e-02, -1.57724898e-02,  8.18107463e-03,\n",
       "        -3.72606446e-03, -1.64890327e-02,  1.08041009e-02,\n",
       "         1.01122679e-02,  1.74866407e-03, -1.00692408e-02,\n",
       "         3.72917973e-03,  1.77870430e-02,  1.15388604e-02,\n",
       "         1.66979171e-02,  2.30163876e-02,  1.45245846e-02,\n",
       "         1.09790787e-02,  2.25082710e-02,  8.88522156e-03,\n",
       "         3.84999276e-03,  6.78812014e-03, -6.29206235e-03,\n",
       "         1.20011866e-02,  5.73713623e-04, -3.58484423e-04,\n",
       "         2.25704573e-02,  1.97128039e-02,  2.48618261e-03,\n",
       "         1.00341532e-02,  3.30620557e-02,  4.67582047e-03,\n",
       "         1.25671867e-02,  9.63101815e-03, -6.98126294e-03,\n",
       "         4.13466897e-03,  7.89871905e-03, -1.68388349e-03,\n",
       "         4.41470556e-03,  2.16695480e-02,  3.36539634e-02,\n",
       "         1.15288170e-02,  1.78786926e-02,  1.03035588e-02,\n",
       "         8.54070950e-03,  2.61212088e-04, -1.41171052e-03,\n",
       "        -1.05745839e-02, -8.94313399e-03,  1.24474419e-02,\n",
       "        -1.49678264e-03,  1.30350972e-02, -3.78952269e-03,\n",
       "         1.29853217e-02, -5.84876491e-03,  8.83117318e-03,\n",
       "         1.09084947e-02,  1.75822247e-02, -2.42153485e-03,\n",
       "         2.69188061e-02],\n",
       "       [ 5.21759735e-03,  1.47629611e-03,  4.69345972e-03,\n",
       "         2.87870294e-03,  4.24716249e-03,  4.83599026e-03,\n",
       "        -1.84578449e-03,  3.33843078e-03,  9.51172377e-04,\n",
       "         7.68936379e-03,  1.14221417e-03,  5.26204892e-03,\n",
       "         5.94653701e-03,  5.13354549e-03,  5.08742314e-03,\n",
       "         1.38968031e-03,  2.90560676e-03,  4.72711818e-03,\n",
       "         3.81981768e-03,  8.63695331e-03,  1.98779325e-03,\n",
       "         4.14589746e-03,  2.45648017e-03,  8.72450136e-03,\n",
       "         3.72051424e-03,  3.63018154e-03,  8.17742944e-03,\n",
       "         2.83566094e-03,  1.01597689e-03,  2.12685089e-03,\n",
       "         6.25073735e-05,  7.25640962e-03,  3.82022094e-03,\n",
       "         4.34174994e-03,  5.85072301e-03,  9.47047374e-04,\n",
       "         2.79816077e-03,  4.49727383e-03,  4.60178824e-03,\n",
       "         1.36057427e-03,  4.69741132e-03,  9.56356467e-04,\n",
       "         1.61343289e-03,  6.29134802e-03,  2.78463890e-03,\n",
       "         5.11198118e-03, -7.20114913e-04,  3.37949023e-03,\n",
       "         2.91588088e-03,  5.00901928e-03,  4.65172669e-03,\n",
       "         5.20490110e-03,  3.70147056e-03,  6.90481300e-03,\n",
       "         2.34888913e-03,  2.18196819e-03,  3.43826832e-03,\n",
       "         5.50945289e-03,  1.69402442e-03,  7.94254523e-03,\n",
       "         4.06751060e-04,  2.06253398e-03,  5.51156874e-04,\n",
       "         3.54768243e-03,  4.68675978e-03,  4.41560568e-03,\n",
       "         3.10626742e-03,  6.76616607e-03,  2.97088153e-03,\n",
       "         5.23018744e-03,  8.21463531e-04,  3.55466595e-03,\n",
       "         3.55025590e-03,  4.21751942e-03,  7.53766426e-06,\n",
       "         3.38028139e-03,  6.64595002e-03,  1.43511093e-03,\n",
       "         2.78131408e-03,  7.84743484e-03,  1.02839316e-03,\n",
       "         3.32346838e-03,  3.19992891e-03,  1.24205020e-04,\n",
       "         6.94080070e-03,  5.62512595e-03,  4.24749590e-03,\n",
       "         4.09889780e-03,  8.02688207e-03,  7.17388117e-04,\n",
       "         4.47497796e-03,  4.97345300e-03,  4.65388224e-03,\n",
       "         3.28435283e-03,  5.25846845e-03,  7.61173666e-03,\n",
       "         3.32462339e-04,  3.95298610e-03,  4.66898642e-03,\n",
       "         2.08678166e-03]], dtype=float32)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.item_factors[1:3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "id": "O3onbJmnt5HG",
    "outputId": "0c7cbbbc-eb8c-4a8f-da75-a16e62693cc3"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.1535235e-01, -1.0716660e+00,  1.9001467e+00, -2.8103048e-01,\n",
       "         2.3507787e-01, -1.3524084e-01, -9.7265404e-01, -2.4441715e-01,\n",
       "        -1.3157841e+00, -9.3033111e-01,  1.3205792e+00,  1.5934669e+00,\n",
       "        -8.7007034e-01,  8.2152611e-01, -1.1706644e+00,  1.0730673e+00,\n",
       "         1.8356223e+00, -6.4666368e-02, -3.6772355e-01,  9.4636500e-01,\n",
       "         2.3708563e+00, -1.0900316e+00, -1.9363825e-01, -1.2721621e+00,\n",
       "        -3.8839546e-01,  1.5143086e+00, -8.0761343e-01, -9.5621413e-01,\n",
       "         1.4447758e+00, -3.5387911e-02,  1.3933902e+00,  8.5588759e-01,\n",
       "         4.9890396e-01,  3.4040824e-01, -3.7110674e-01,  3.9586887e-01,\n",
       "        -4.4984985e-02,  1.0853641e+00,  1.0416827e+00, -2.0454068e+00,\n",
       "         2.1352434e+00, -1.4058716e+00,  8.2302362e-01,  2.8762394e-01,\n",
       "        -8.2267590e-02, -9.1558552e-01,  5.0190097e-01,  2.0039406e-01,\n",
       "         1.2773964e+00, -4.9887997e-01, -1.5381695e-02, -7.4103689e-01,\n",
       "        -4.8554859e-01, -6.2013620e-01,  1.2602403e+00,  3.7264615e-01,\n",
       "         1.6895621e-01, -1.3288108e+00,  7.5886017e-01,  3.5683268e-01,\n",
       "        -3.4131634e-01,  1.8973587e-01,  2.9325524e-01, -7.4078739e-01,\n",
       "        -1.2132510e+00, -1.0879766e+00, -1.3704516e+00, -1.2282028e+00,\n",
       "        -9.8826337e-01,  4.5458439e-01,  2.5428922e+00,  1.1061906e+00,\n",
       "         9.2474401e-01,  1.5637769e+00, -1.2372558e+00, -9.5266867e-01,\n",
       "         3.3413932e-01,  8.3561289e-01, -5.5887586e-01,  7.6054811e-02,\n",
       "         1.9956827e+00,  9.4774431e-01,  3.6637652e-01,  8.2821363e-01,\n",
       "         2.8309381e-01, -9.9692512e-01,  9.8618686e-01,  8.0894047e-01,\n",
       "        -4.6432391e-01, -7.3879558e-01, -1.4049910e+00,  3.1375384e-01,\n",
       "         7.0995593e-01, -3.4533828e-01,  1.0314369e+00, -7.4499923e-01,\n",
       "        -1.0274127e+00, -5.7535094e-01, -1.9709327e+00,  1.4919670e+00],\n",
       "       [-1.5587401e+00,  1.5053092e-01,  3.7092552e-02,  2.1527238e+00,\n",
       "        -2.2145588e+00, -6.1379347e-02,  1.2396275e+00, -8.3214724e-01,\n",
       "        -3.2939258e+00, -5.2348149e-01,  9.3661207e-01, -8.3603543e-01,\n",
       "        -2.0481503e+00,  3.6520573e-01,  2.1556497e+00,  1.6638597e+00,\n",
       "         1.0686793e+00,  1.4715923e+00, -1.3041624e+00, -2.5738211e+00,\n",
       "         1.6351489e+00,  2.6861623e-01,  1.4985343e+00, -3.6418435e-01,\n",
       "         6.7551094e-01,  1.4531764e+00, -9.3211579e-01,  1.6065925e+00,\n",
       "        -5.6125438e-01,  1.5840977e+00,  1.1768103e+00,  2.9195817e+00,\n",
       "         3.0073445e+00, -2.6590629e-03, -6.4741218e-01, -1.6547465e-01,\n",
       "        -3.2860899e-01, -1.3454194e+00, -1.3172647e-01, -1.9245317e+00,\n",
       "        -3.2763949e-01,  1.6461329e+00,  1.2353618e+00,  8.4044081e-01,\n",
       "         1.9554125e+00,  1.3067812e+00,  3.1975982e+00, -1.4149319e-01,\n",
       "        -1.8368236e+00, -1.0103904e+00,  5.0911957e-01,  5.5677569e-01,\n",
       "         6.9721764e-01, -5.6430489e-01,  2.2003100e+00, -1.0744971e+00,\n",
       "         1.6468230e+00, -2.3111634e+00,  1.3065448e+00, -8.5009754e-01,\n",
       "         2.0129523e+00, -1.7714916e-01, -9.0549275e-02, -7.5850022e-01,\n",
       "        -6.3388091e-01,  1.2075551e+00, -3.2875051e+00, -1.0517368e+00,\n",
       "        -4.8032269e-01,  1.6501316e-01, -3.2218367e-01,  1.8979825e+00,\n",
       "         1.3875642e+00,  1.9148558e+00,  9.3831289e-01,  9.1719218e-02,\n",
       "        -3.4196714e-01,  1.0367199e+00,  2.6459680e+00, -2.4039178e+00,\n",
       "        -3.1851164e-01, -4.1336271e-01, -5.2495323e-02, -4.7513500e-01,\n",
       "        -2.1291137e+00, -2.8807511e+00,  1.7764181e+00,  2.3209753e+00,\n",
       "        -2.4233973e+00,  2.3937972e+00, -5.7148945e-01,  6.0630590e-01,\n",
       "         5.6338543e-01,  9.7472930e-01, -6.0403675e-02, -5.1794976e-01,\n",
       "         1.6027211e+00,  1.0213125e-03,  1.5301393e+00, -2.9542151e-01]],\n",
       "      dtype=float32)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.user_factors[1:3]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "n2ymVmqct5HH"
   },
   "source": [
    "## Configure Pinecone"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "YSRAKA56t5HH"
   },
   "source": [
    "Install and setup Pinecone"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "id": "oxZDkCjht5HH"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mWARNING: You are using pip version 22.0.4; however, version 23.1.2 is available.\n",
      "You should consider upgrading via the '/home/jelena/.pyenv/versions/3.8.16/envs/pinecone-product-recommender/bin/python3.8 -m pip install --upgrade pip' command.\u001b[0m\u001b[33m\n",
      "\u001b[0m"
     ]
    }
   ],
   "source": [
    "!pip install -qU pinecone-client"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "id": "mOEmO-yft5HH"
   },
   "outputs": [],
   "source": [
    "from pinecone import Pinecone"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "id": "3_ykVLT6t5HH"
   },
   "outputs": [],
   "source": [
    "# Load Pinecone API key\n",
    "api_key = os.getenv('PINECONE_API_KEY') or 'YOUR_API_KEY'\n",
    "# Set Pinecone environment. Find next to API key in console\n",
    "env = os.getenv('PINECONE_ENVIRONMENT') or \"YOUR_ENV\"\n",
    "\n",
    "pc = Pinecone(api_key=api_key)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "KpWkJa-Dt5HH"
   },
   "source": [
    "[Get a Pinecone API key](http://app.pinecone.io/) if you don't have one."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "id": "By8wu8B3t5HH",
    "outputId": "57b1aa59-d440-4f83-e3bd-3170d4f39a94"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#List all present indexes associated with your key, should be empty on the first run\n",
    "pinecone.list_indexes().names()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "YQx7UIDOt5HI"
   },
   "source": [
    "**Create an Index**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "id": "4VDr7Wqst5HI"
   },
   "outputs": [],
   "source": [
    "# Set a name for your index\n",
    "index_name = 'product-recommender'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "id": "ufHsF0o4t5HI"
   },
   "outputs": [],
   "source": [
    "# Make sure service with the same name does not exist\n",
    "if index_name in pinecone.list_indexes().names():\n",
    "    pinecone.delete_index(index_name)\n",
    "pinecone.create_index(name=index_name, dimension=100)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "v50hrlJNt5HI"
   },
   "source": [
    "**Connect to the new index**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "id": "ONg-J3ost5HI"
   },
   "outputs": [],
   "source": [
    "index = pinecone.Index(index_name=index_name)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "8BjfHb2Ht5HI"
   },
   "source": [
    "## Load Data"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "0-2K-g4-t5HJ"
   },
   "source": [
    "Uploading all items (products that one can buy) and displaying some examples of products and their vector representations.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[33mWARNING: You are using pip version 22.0.4; however, version 23.1.2 is available.\n",
      "You should consider upgrading via the '/home/jelena/.pyenv/versions/3.8.16/envs/pinecone-product-recommender/bin/python3.8 -m pip install --upgrade pip' command.\u001b[0m\u001b[33m\n",
      "\u001b[0m"
     ]
    }
   ],
   "source": [
    "!pip install -qU torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "id": "NOOPF9zOt5HJ",
    "outputId": "397b0227-0394-4fd6-e97c-bbd0ba7422ea"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('1',\n",
       "  [0.007623022887855768,\n",
       "   -0.0018749987939372659,\n",
       "   -0.0002671325346454978,\n",
       "   -0.0019839361775666475,\n",
       "   0.012589375488460064,\n",
       "   0.022616468369960785,\n",
       "   -0.0029845251701772213,\n",
       "   0.001483042724430561,\n",
       "   0.004130321554839611,\n",
       "   0.014062315225601196,\n",
       "   0.007028672378510237,\n",
       "   0.017575189471244812,\n",
       "   -0.008487655781209469,\n",
       "   0.007234435528516769,\n",
       "   0.0011922105913981795,\n",
       "   0.021330712363123894,\n",
       "   0.01949598826467991,\n",
       "   0.0055589438416063786,\n",
       "   0.0005246000946499407,\n",
       "   0.00455727893859148,\n",
       "   0.008326052688062191,\n",
       "   0.002581121399998665,\n",
       "   -0.0004822195041924715,\n",
       "   -0.012043976224958897,\n",
       "   0.0024738165084272623,\n",
       "   0.012800917960703373,\n",
       "   0.002085306216031313,\n",
       "   -0.003331454936414957,\n",
       "   0.019255518913269043,\n",
       "   0.004345945548266172,\n",
       "   -0.006639685947448015,\n",
       "   0.00556971225887537,\n",
       "   0.0067274365574121475,\n",
       "   0.0027871401980519295,\n",
       "   -0.002836253959685564,\n",
       "   -0.006032831035554409,\n",
       "   0.008454968221485615,\n",
       "   0.011893117800354958,\n",
       "   0.02100340649485588,\n",
       "   -0.016892924904823303,\n",
       "   0.017926765605807304,\n",
       "   -0.009869110770523548,\n",
       "   0.012677340768277645,\n",
       "   -0.015772489830851555,\n",
       "   0.008181074634194374,\n",
       "   -0.003726064460352063,\n",
       "   -0.01648903265595436,\n",
       "   0.010804100893437862,\n",
       "   0.010112267918884754,\n",
       "   0.0017486640717834234,\n",
       "   -0.010069240815937519,\n",
       "   0.003729179734364152,\n",
       "   0.017787043005228043,\n",
       "   0.011538860388100147,\n",
       "   0.016697917133569717,\n",
       "   0.023016387596726418,\n",
       "   0.014524584636092186,\n",
       "   0.010979078710079193,\n",
       "   0.022508271038532257,\n",
       "   0.008885221555829048,\n",
       "   0.003849992761388421,\n",
       "   0.00678812013939023,\n",
       "   -0.006292062345892191,\n",
       "   0.012001186609268188,\n",
       "   0.0005737136234529316,\n",
       "   -0.0003584844234865159,\n",
       "   0.022570457309484482,\n",
       "   0.01971280388534069,\n",
       "   0.0024861826095730066,\n",
       "   0.010034153237938881,\n",
       "   0.033062055706977844,\n",
       "   0.004675820469856262,\n",
       "   0.01256718672811985,\n",
       "   0.009631018154323101,\n",
       "   -0.0069812629371881485,\n",
       "   0.004134668968617916,\n",
       "   0.007898719049990177,\n",
       "   -0.0016838834853842854,\n",
       "   0.0044147055596113205,\n",
       "   0.021669548004865646,\n",
       "   0.03365396335721016,\n",
       "   0.011528817005455494,\n",
       "   0.017878692597150803,\n",
       "   0.01030355878174305,\n",
       "   0.008540709502995014,\n",
       "   0.00026121208793483675,\n",
       "   -0.0014117105165496469,\n",
       "   -0.010574583895504475,\n",
       "   -0.008943133987486362,\n",
       "   0.012447441928088665,\n",
       "   -0.001496782642789185,\n",
       "   0.013035097159445286,\n",
       "   -0.003789522685110569,\n",
       "   0.012985321693122387,\n",
       "   -0.005848764907568693,\n",
       "   0.008831173181533813,\n",
       "   0.01090849470347166,\n",
       "   0.017582224681973457,\n",
       "   -0.002421534853056073,\n",
       "   0.02691880613565445],\n",
       "  {'title': 'Chocolate Sandwich Cookies'}),\n",
       " ('2',\n",
       "  [0.005217597354203463,\n",
       "   0.0014762961072847247,\n",
       "   0.004693459719419479,\n",
       "   0.0028787029441446066,\n",
       "   0.004247162491083145,\n",
       "   0.004835990257561207,\n",
       "   -0.0018457844853401184,\n",
       "   0.0033384307753294706,\n",
       "   0.0009511723765172064,\n",
       "   0.007689363788813353,\n",
       "   0.0011422141687944531,\n",
       "   0.005262048915028572,\n",
       "   0.005946537014096975,\n",
       "   0.005133545491844416,\n",
       "   0.005087423138320446,\n",
       "   0.0013896803138777614,\n",
       "   0.002905606757849455,\n",
       "   0.00472711818292737,\n",
       "   0.003819817677140236,\n",
       "   0.008636953309178352,\n",
       "   0.0019877932500094175,\n",
       "   0.004145897459238768,\n",
       "   0.002456480171531439,\n",
       "   0.008724501356482506,\n",
       "   0.0037205142434686422,\n",
       "   0.0036301815416663885,\n",
       "   0.008177429437637329,\n",
       "   0.0028356609400361776,\n",
       "   0.0010159768862649798,\n",
       "   0.002126850886270404,\n",
       "   6.250737351365387e-05,\n",
       "   0.007256409619003534,\n",
       "   0.0038202209398150444,\n",
       "   0.00434174994006753,\n",
       "   0.005850723013281822,\n",
       "   0.0009470473742112517,\n",
       "   0.002798160770907998,\n",
       "   0.004497273825109005,\n",
       "   0.004601788241416216,\n",
       "   0.001360574271529913,\n",
       "   0.004697411321103573,\n",
       "   0.0009563564672134817,\n",
       "   0.0016134328907355666,\n",
       "   0.006291348021477461,\n",
       "   0.002784638898447156,\n",
       "   0.005111981183290482,\n",
       "   -0.0007201149128377438,\n",
       "   0.003379490226507187,\n",
       "   0.002915880875661969,\n",
       "   0.005009019281715155,\n",
       "   0.0046517266891896725,\n",
       "   0.005204901099205017,\n",
       "   0.003701470559462905,\n",
       "   0.0069048129953444,\n",
       "   0.0023488891310989857,\n",
       "   0.0021819681860506535,\n",
       "   0.0034382683224976063,\n",
       "   0.005509452894330025,\n",
       "   0.0016940244240686297,\n",
       "   0.007942545227706432,\n",
       "   0.0004067510599270463,\n",
       "   0.0020625339820981026,\n",
       "   0.0005511568742804229,\n",
       "   0.0035476824268698692,\n",
       "   0.004686759784817696,\n",
       "   0.004415605682879686,\n",
       "   0.003106267424300313,\n",
       "   0.0067661660723388195,\n",
       "   0.002970881527289748,\n",
       "   0.005230187438428402,\n",
       "   0.000821463530883193,\n",
       "   0.0035546659491956234,\n",
       "   0.0035502559039741755,\n",
       "   0.004217519424855709,\n",
       "   7.537664259871235e-06,\n",
       "   0.0033802813850343227,\n",
       "   0.006645950023084879,\n",
       "   0.0014351109275594354,\n",
       "   0.0027813140768557787,\n",
       "   0.007847434841096401,\n",
       "   0.0010283931624144316,\n",
       "   0.003323468379676342,\n",
       "   0.003199928905814886,\n",
       "   0.0001242050202563405,\n",
       "   0.006940800696611404,\n",
       "   0.005625125952064991,\n",
       "   0.0042474959045648575,\n",
       "   0.00409889779984951,\n",
       "   0.008026882074773312,\n",
       "   0.0007173881167545915,\n",
       "   0.00447497796267271,\n",
       "   0.004973453003913164,\n",
       "   0.00465388223528862,\n",
       "   0.003284352831542492,\n",
       "   0.005258468445390463,\n",
       "   0.0076117366552352905,\n",
       "   0.0003324623394291848,\n",
       "   0.003952986095100641,\n",
       "   0.004668986424803734,\n",
       "   0.0020867816638201475],\n",
       "  {'title': 'All-Seasons Salt'})]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import torch\n",
    "\n",
    "# Get all of the items\n",
    "all_items_titles = [{'title': title} for title in products_lookup['product_name']]\n",
    "all_items_ids = [str(product_id) for product_id in products_lookup['product_id']]\n",
    "\n",
    "# Transform items into factors\n",
    "items_factors = model.item_factors\n",
    "\n",
    "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n",
    "item_embeddings = items_factors[1:].to_numpy().tolist() if device == \"cuda\" else items_factors[1:].tolist()\n",
    "\n",
    "# Prepare item factors for upload\n",
    "items_to_insert = list(zip(all_items_ids, item_embeddings, all_items_titles))\n",
    "display(items_to_insert[:2])"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "YnEHPvuTt5HJ"
   },
   "source": [
    "**Insert items into the index**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "id": "BYwN6MI1t5HJ",
    "outputId": "ddcbfcd4-f620-414c-e59d-220dd28d9224"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Index statistics before upsert: {'dimension': 100,\n",
      " 'index_fullness': 0.0,\n",
      " 'namespaces': {},\n",
      " 'total_vector_count': 0}\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 497/497 [05:36<00:00,  1.48it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Index statistics after upsert: {'dimension': 100,\n",
      " 'index_fullness': 0.0,\n",
      " 'namespaces': {'': {'vector_count': 49688}},\n",
      " 'total_vector_count': 49688}\n"
     ]
    }
   ],
   "source": [
    "from tqdm.auto import tqdm\n",
    "\n",
    "BATCH_SIZE = 100\n",
    "\n",
    "print('Index statistics before upsert:', index.describe_index_stats())\n",
    "\n",
    "for i in tqdm(range(0, len(items_to_insert), BATCH_SIZE)):\n",
    "        index.upsert(vectors=items_to_insert[i:i+BATCH_SIZE])\n",
    "\n",
    "print('Index statistics after upsert:', index.describe_index_stats())"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "ibNMrxyRt5HK"
   },
   "source": [
    "This is a helper method for analysing recommendations later.\n",
    "This method returns top N products that someone bought in the past (based on product quantity)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "id": "Uzgk5Od0t5HK"
   },
   "outputs": [],
   "source": [
    "def products_bought_by_user_in_the_past(user_id: int, top: int = 10):\n",
    "\n",
    "    selected = data[data.user_id == user_id].sort_values(by=['total_orders'], ascending=False)\n",
    "\n",
    "    selected['product_name'] = selected['product_id'].map(products_lookup.set_index('product_id')['product_name'])\n",
    "    selected = selected[['product_id', 'product_name', 'total_orders']].reset_index(drop=True)\n",
    "    if selected.shape[0] < top:\n",
    "        return selected\n",
    "\n",
    "    return selected[:top]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "id": "1Gthi5Dkt5HK",
    "outputId": "2acc3a2f-2c14-41ae-e93e-b2b3190055e2"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user_id</th>\n",
       "      <th>product_id</th>\n",
       "      <th>total_orders</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>13863744</th>\n",
       "      <td>206209</td>\n",
       "      <td>48697</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13863745</th>\n",
       "      <td>206209</td>\n",
       "      <td>48742</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13863746</th>\n",
       "      <td>206210</td>\n",
       "      <td>22802</td>\n",
       "      <td>97</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13863747</th>\n",
       "      <td>206211</td>\n",
       "      <td>26834</td>\n",
       "      <td>89</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13863748</th>\n",
       "      <td>206211</td>\n",
       "      <td>12590</td>\n",
       "      <td>77</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          user_id  product_id  total_orders\n",
       "13863744   206209       48697             1\n",
       "13863745   206209       48742             2\n",
       "13863746   206210       22802            97\n",
       "13863747   206211       26834            89\n",
       "13863748   206211       12590            77"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.tail()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "Xah1FIs0t5HK"
   },
   "source": [
    "## Query for Recommendations"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "ULyVnHEXt5HK"
   },
   "source": [
    "We are now retrieving user factors for users that we have manually created before for testing purposes. Besides these users, we are adding a random existing user. We are also displaying these users so you can see what these factors look like."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "id": "Wwl7yFKTt5HK",
    "outputId": "b3baef91-2d00-4231-e546-2ee966f62d4d"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.313707  , -0.27664858, -1.2828674 ,  1.7485007 , -0.99290836,\n",
       "         2.2764893 , -0.9494704 ,  1.1454551 , -2.0393448 , -1.6061454 ,\n",
       "         0.5251323 , -1.3181114 ,  1.0427406 ,  1.8733109 , -2.549778  ,\n",
       "         1.3321211 , -0.3133029 ,  2.208259  , -2.3020349 ,  0.5815489 ,\n",
       "        -0.37377855,  0.7690419 , -0.40076098, -2.4527717 ,  1.2445227 ,\n",
       "        -0.46194887, -2.7551808 , -1.1535347 ,  0.10361311,  2.6116688 ,\n",
       "        -1.0924482 ,  1.6089348 , -2.4051344 , -2.931227  ,  1.8216416 ,\n",
       "         1.0059888 ,  1.7596883 , -2.4735103 , -1.3774238 ,  1.2440904 ,\n",
       "        -2.4833293 , -0.39517453, -0.00621076,  3.1343987 , -0.8446826 ,\n",
       "        -1.5209638 ,  0.83655167,  1.7331113 , -0.35771912,  1.4926167 ,\n",
       "         0.42455527,  0.6774385 , -0.63032067,  0.14995454, -1.2719532 ,\n",
       "         1.0312878 ,  1.2454114 , -2.1102207 , -2.3025262 ,  0.55968195,\n",
       "        -0.18068558,  0.99221903,  0.8804258 ,  0.9581545 , -0.7357688 ,\n",
       "        -1.3392165 , -0.37945822,  1.0634457 , -0.10247187,  0.22213912,\n",
       "         0.10265829, -1.0366185 , -0.6038233 ,  0.47490817,  2.7055511 ,\n",
       "         2.5368512 , -0.5959401 ,  0.13280135,  0.67197865,  0.12398392,\n",
       "        -0.04903562,  0.81579864,  0.2347543 , -0.9798626 ,  0.2947345 ,\n",
       "         0.2806802 ,  1.1976005 ,  2.1994352 ,  0.26454824,  1.1742004 ,\n",
       "         0.11709324,  1.6044425 , -0.5988262 ,  0.15046799,  0.46880785,\n",
       "        -0.35391572, -0.08479875,  1.7974043 , -2.7378693 , -0.89177626],\n",
       "       [-1.113506  ,  0.646045  ,  0.91660035,  3.427136  , -1.8506187 ,\n",
       "        -2.001958  , -1.167917  , -0.09067711, -1.2732714 ,  0.72084534,\n",
       "         0.92990404, -0.2793406 ,  2.5933106 ,  0.2095659 ,  0.20489155,\n",
       "         2.6076956 ,  1.4788582 ,  0.55408037,  0.7565834 , -0.6248087 ,\n",
       "        -1.0415096 , -1.0918716 ,  1.6078566 ,  1.0329262 , -2.4481158 ,\n",
       "         1.5047243 , -0.5709003 , -1.8746959 ,  0.2135229 ,  2.4907224 ,\n",
       "         0.19642703,  1.4449238 ,  1.6527305 , -0.17461014,  0.11057296,\n",
       "        -1.7177945 , -0.04621175,  1.2366726 ,  0.8969147 , -1.5486971 ,\n",
       "        -0.3412704 , -2.034647  ,  0.6454408 ,  0.14385808,  2.1624665 ,\n",
       "         0.7950704 ,  1.4016353 , -0.1812926 ,  0.5354293 , -1.378532  ,\n",
       "         0.01187539, -0.00947361, -1.6387362 , -1.3973973 ,  0.31152153,\n",
       "         1.370239  , -0.3467708 , -1.2985501 ,  2.492775  , -0.75529194,\n",
       "        -0.21149556,  1.1047683 ,  2.1180177 , -2.7552977 , -0.14160857,\n",
       "         0.7567414 ,  0.12927827, -1.1602536 , -1.2509437 , -1.0854826 ,\n",
       "        -0.18008146, -0.00589125,  0.5193577 ,  0.80703855,  1.7236317 ,\n",
       "        -0.07526795, -0.41325498,  1.6021116 ,  5.0426197 , -0.05752076,\n",
       "         1.3786825 , -2.10659   , -0.37388846,  1.1092849 , -3.7238026 ,\n",
       "         0.04807726,  0.6400418 ,  2.1282876 , -2.405108  ,  2.343005  ,\n",
       "         0.02623899, -1.3713418 ,  0.13835156, -0.68146217,  1.8052037 ,\n",
       "         0.5837893 , -1.3996686 , -1.2638658 ,  1.2598401 ,  0.02347608]],\n",
       "      dtype=float32)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "user_ids = [206210, 206211, 103593]\n",
    "user_factors = model.user_factors[user_to_index[user_ids]]\n",
    "\n",
    "display(user_factors[1:])"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "d2rlTIuyt5HK"
   },
   "source": [
    "### Model recommendations\n",
    "\n",
    "We will now retrieve recommendations from our model directly, just to have these results as a baseline."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "id": "IM9lyHTVt5HL",
    "outputId": "fdb5f8e4-57a0-41c8-9ffb-34c629fec7e5"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model recommendations\n",
      "\n",
      "Time needed for retrieving recommended products: 0.08775425699968764 seconds.\n",
      "\n",
      "\n",
      "Recommendations for person 0:\n",
      "['Sparkling Water']\n",
      "['Mineral Water']\n",
      "['Sparkling Natural Mineral Water']\n",
      "['Soda']\n",
      "['Spring Water']\n",
      "['Smartwater']\n",
      "['Zero Calorie Cola']\n",
      "['Sparkling Mineral Water']\n",
      "['Drinking Water']\n",
      "['Distilled Water']\n",
      "\n",
      "Recommendations for person 1:\n",
      "['Baby Wipes Sensitive']\n",
      "['Organic Garbanzo Beans']\n",
      "['Ezekiel 4:9 Bread Organic Sprouted Whole Grain']\n",
      "['Chocolate Ice Cream']\n",
      "['YoBaby Peach Pear Yogurt']\n",
      "['Free and Gentle High Efficiency Liquid Laundry Detergent']\n",
      "['Baby Wash & Shampoo']\n",
      "['No More Tears Baby Shampoo']\n",
      "['White Buttermints']\n",
      "['Eggo Pancakes Minis']\n",
      "\n",
      "Recommendations for person 2:\n",
      "['Organic Blackberries']\n",
      "['Peach']\n",
      "['Organic Bosc Pear']\n",
      "['Organic Strawberries']\n",
      "['Organic Blueberries']\n",
      "['Red Plums']\n",
      "['Clementines, Bag']\n",
      "['Organic Bartlett Pear']\n",
      "['Blood Oranges']\n",
      "['Organic Fuji Apple']\n"
     ]
    }
   ],
   "source": [
    "print(\"Model recommendations\\n\")\n",
    "\n",
    "start_time = time.process_time()\n",
    "recommendations0 = model.recommend(userid=user_ids[0], user_items=sparse_user_product[0])\n",
    "recommendations1 = model.recommend(userid=user_ids[1], user_items=sparse_user_product[1])\n",
    "recommendations2 = model.recommend(userid=user_ids[2], user_items=sparse_user_product[2])\n",
    "print(\"Time needed for retrieving recommended products: \" + str(time.process_time() - start_time) + ' seconds.\\n')\n",
    "\n",
    "print('\\nRecommendations for person 0:')\n",
    "for recommendation in recommendations0[0]:\n",
    "    print(products_lookup[products_lookup.product_id == recommendation]['product_name'].values)\n",
    "\n",
    "print('\\nRecommendations for person 1:')\n",
    "for recommendation in recommendations1[0]:\n",
    "    print(products_lookup[products_lookup.product_id == recommendation]['product_name'].values)\n",
    "\n",
    "print('\\nRecommendations for person 2:')\n",
    "for recommendation in recommendations2[0]:\n",
    "    print(products_lookup[products_lookup.product_id == recommendation]['product_name'].values)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "wTh61ou3t5HL"
   },
   "source": [
    "### Query the index\n",
    "\n",
    "Let's now query the index to check how quickly we retrieve results. Please note that query speed depends in part on your internet connection."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "id": "UiZg4Iset5HL",
    "outputId": "06898130-2d66-4860-d7ea-e7ac6c9c92f6"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time needed for retrieving recommended products using Pinecone: 0.016210021000006236 seconds.\n",
      "\n",
      "user_id=206210\n",
      "Recommendation: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>products</th>\n",
       "      <th>scores</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Mineral Water</td>\n",
       "      <td>0.927818</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Zero Calorie Cola</td>\n",
       "      <td>0.660643</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Orange &amp; Lemon Flavor Variety Pack Sparkling F...</td>\n",
       "      <td>0.640357</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Sparkling Water</td>\n",
       "      <td>0.617592</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Extra Fancy Unsalted Mixed Nuts</td>\n",
       "      <td>0.596714</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Popcorn</td>\n",
       "      <td>0.592487</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Organic Variety Pack</td>\n",
       "      <td>0.586585</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Drinking Water</td>\n",
       "      <td>0.585892</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Tall Kitchen Bag With Febreze Odor Shield</td>\n",
       "      <td>0.569821</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>Milk Chocolate Almonds</td>\n",
       "      <td>0.561412</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                            products    scores\n",
       "0                                      Mineral Water  0.927818\n",
       "1                                  Zero Calorie Cola  0.660643\n",
       "2  Orange & Lemon Flavor Variety Pack Sparkling F...  0.640357\n",
       "3                                    Sparkling Water  0.617592\n",
       "4                    Extra Fancy Unsalted Mixed Nuts  0.596714\n",
       "5                                            Popcorn  0.592487\n",
       "6                               Organic Variety Pack  0.586585\n",
       "7                                     Drinking Water  0.585892\n",
       "8          Tall Kitchen Bag With Febreze Odor Shield  0.569821\n",
       "9                             Milk Chocolate Almonds  0.561412"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Top buys from the past: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>product_id</th>\n",
       "      <th>product_name</th>\n",
       "      <th>total_orders</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>22802</td>\n",
       "      <td>Mineral Water</td>\n",
       "      <td>97</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   product_id   product_name  total_orders\n",
       "0       22802  Mineral Water            97"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "user_id=206211\n",
      "Recommendation: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>products</th>\n",
       "      <th>scores</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Baby Wash &amp; Shampoo</td>\n",
       "      <td>0.705169</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>No More Tears Baby Shampoo</td>\n",
       "      <td>0.675753</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Baby Wipes Sensitive</td>\n",
       "      <td>0.563419</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Size 6 Baby Dry Diapers</td>\n",
       "      <td>0.525253</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Graduates Lil' Crunchies Mild Cheddar Corn Snacks</td>\n",
       "      <td>0.502849</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Sensitive Infant Formula for Fussiness and Gas</td>\n",
       "      <td>0.494810</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Size 5 Cruisers Diapers Super Pack</td>\n",
       "      <td>0.494335</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Grow &amp; Gain Chocolate Shake Nutritional Drink</td>\n",
       "      <td>0.494275</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Stage 1 Newborn Hypoallergenic Liquid Detergent</td>\n",
       "      <td>0.492494</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>Strawberry Yogurt Melts</td>\n",
       "      <td>0.490631</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                            products    scores\n",
       "0                                Baby Wash & Shampoo  0.705169\n",
       "1                         No More Tears Baby Shampoo  0.675753\n",
       "2                               Baby Wipes Sensitive  0.563419\n",
       "3                            Size 6 Baby Dry Diapers  0.525253\n",
       "4  Graduates Lil' Crunchies Mild Cheddar Corn Snacks  0.502849\n",
       "5     Sensitive Infant Formula for Fussiness and Gas  0.494810\n",
       "6                 Size 5 Cruisers Diapers Super Pack  0.494335\n",
       "7      Grow & Gain Chocolate Shake Nutritional Drink  0.494275\n",
       "8    Stage 1 Newborn Hypoallergenic Liquid Detergent  0.492494\n",
       "9                            Strawberry Yogurt Melts  0.490631"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Top buys from the past: \n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>product_id</th>\n",
       "      <th>product_name</th>\n",
       "      <th>total_orders</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>26834</td>\n",
       "      <td>No More Tears Baby Shampoo</td>\n",
       "      <td>89</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>12590</td>\n",
       "      <td>Baby Wash &amp; Shampoo</td>\n",
       "      <td>77</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   product_id                product_name  total_orders\n",
       "0       26834  No More Tears Baby Shampoo            89\n",
       "1       12590         Baby Wash & Shampoo            77"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Query by user factors\n",
    "user_embeddings = user_factors.to_numpy()[:-1].tolist() if device == \"cuda\" else user_factors[:-1].tolist()\n",
    "\n",
    "start_time = time.process_time()\n",
    "query_results = index.query(queries=user_embeddings, top_k=10, include_metadata=True)\n",
    "print(\"Time needed for retrieving recommended products using Pinecone: \" + str(time.process_time() - start_time) + ' seconds.\\n')\n",
    "\n",
    "for _id, res in zip(user_ids, query_results.results):\n",
    "    print(f'user_id={_id}')\n",
    "    df = pd.DataFrame(\n",
    "        {\n",
    "            'products': [match.metadata['title'] for match in res.matches],\n",
    "            'scores': [match.score for match in res.matches]\n",
    "        }\n",
    "    )\n",
    "    print(\"Recommendation: \")\n",
    "    display(df)\n",
    "    print(\"Top buys from the past: \")\n",
    "    display(products_bought_by_user_in_the_past(_id, top=15))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "Dkxi6IYbt5HL"
   },
   "source": [
    "*Note* The inference using Pinecone is much faster compared to retrieving recommendations from a model directly. Please note that this result depends on your internet connection as well. "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "Jl64xOvKt5HL"
   },
   "source": [
    "All that’s left to do is surface these recommendations on the shopping site, or feed them into other applications."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "HUvu0FG9t5HM"
   },
   "source": [
    "## Clean up"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "QTpsePdJt5HM"
   },
   "source": [
    "Delete the index once you are sure that you do not want to use it anymore. Once it is deleted, you cannot reuse it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "id": "7gCA-7kbt5HM"
   },
   "outputs": [],
   "source": [
    "pinecone.delete_index(index_name)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "Ece-xKrYt5HM"
   },
   "source": [
    "## Summary"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {
    "id": "FXywcRrYt5HM"
   },
   "source": [
    "In this example we used [Pinecone](https://www.pinecone.io/) to build and deploy a product recommendation engine that uses collaborative filtering, relatively quickly.\n",
    "\n",
    "Once deployed, the product recommendation engine can index new data, retrieve recommendations in milliseconds, and send results to production applications."
   ]
  }
 ],
 "metadata": {
  "colab": {
   "name": "product_recommender.ipynb",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "base",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.16"
  },
  "vscode": {
   "interpreter": {
    "hash": "5fe10bf018ef3e697f9035d60bf60847932a12bface18908407fd371fe880db9"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
